//package com.lplb.gateway.filter;
//
//
//import com.alibaba.fastjson.JSONObject;
//import com.gateway.error.ErrorException;
//import com.gateway.filter.properties.AuthProperties;
//import com.gateway.result.ResultType;
//import com.gateway.utils.SqlEncodeUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.cloud.gateway.support.CachedBodyOutputMessage;
//import org.springframework.core.Ordered;
//import org.springframework.core.io.buffer.DataBuffer;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
//import org.springframework.stereotype.Component;
//import org.springframework.util.MultiValueMap;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Flux;
//import reactor.core.publisher.Mono;
//
//import java.util.Map;
//import java.util.Objects;
//
//
///**
// *  Request 请求参数过滤
// * 参考文章一 body数据处理： https://blog.csdn.net/tianyaleixiaowu/article/details/83375246
// * 参考文章二 请求参数获取：https://blog.csdn.net/fuck487/article/details/85166162
// *
// * @author ws
// * @mail 1720696548@qq.com
// * @date 2020/2/14 0014 0:21
// */
//@Component
//@Slf4j
//@SuppressWarnings("all")
//public class RequestFilter implements GlobalFilter, Ordered {
//    /**
//     * 过滤执行顺序
//     */
//    private int order;
//
//    public RequestFilter(int order) {
//        this.order = order;
//    }
//
//    @Override
//    public int getOrder() {
//        return order;
//    }
//
//
//    @Autowired
//    private AuthProperties authProperties;
//
//
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
////        // req
////        ServerHttpRequest serverHttpRequest = exchange.getRequest();
////        // 重新构造request，参考ModifyRequestBodyGatewayFilterFactory
////        ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
////        // 请求方式 --   //if (method == HttpMethod.POST || method == HttpMethod.PUT || method == HttpMethod.DELETE || method == HttpMethod.GET) {
////        String method = serverHttpRequest.getMethodValue();
////        // 请求参数类型
////        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
////        // 不对文件上传做处理
////        if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(mediaType)) {
////            return chain.filter(exchange);
////        }
////        //  json 格式参数传参
////        if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType) || MediaType.APPLICATION_JSON_UTF8.isCompatibleWith(mediaType)) {
////            Mono<String> modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
////                //验签，xss攻击等
////                String newBody = handleBody(body);
////                //临时保存数据
////                exchange.getResponse().getHeaders().add("bodyStr", newBody);
////                //返回数据
////                return Mono.just(newBody);
////                // return Mono.empty();
////            });
////            BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
////            HttpHeaders headers = new HttpHeaders();
////            headers.putAll(exchange.getRequest().getHeaders());
////            //猜测这个就是之前报400错误的元凶，之前修改了body但是没有重新写content length
////            headers.remove("Content-Length");
////            //CachedBodyOutputMessage
////            CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
////            // return开始执行 serverRequest.bodyToMono方法
////            return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
////                ServerHttpRequest decorator = this.decorate(exchange, headers, outputMessage);
////                return returnMono(chain, exchange.mutate().request(decorator).build());
////            }));
////        } else {
////            //  非json 格式参数传参，得到 queryParams 参数后，做你想做的事，可以处理sql 注入， xss 攻击处理等,java中URL 的编码和解码函数java.net.URLEncoder.encode(String s)和java.net.URLDecoder.decode(String s);
////            MultiValueMap<String, String> queryParams = serverHttpRequest.getQueryParams();
////            URI uri = serverHttpRequest.getURI();
////            //  重写uri参数，自定义handleParam 方法进行参数替换/过滤
////            URI newUri = UriComponentsBuilder.fromUri(uri)
////                    .replaceQuery(this.handleParam(queryParams))
////                    .build(true)
////                    .toUri();
////            //下面的将请求体再次封装写回到request里，传到下一级，否则，由于请求体已被消费，后续的服务将取不到值
////            ServerHttpRequest request = serverHttpRequest.mutate().uri(newUri).build();
////            // 临时保存请求参数
////            exchange.getResponse().getHeaders().add("queryParams", queryParams.toString());
////            //封装request，传给下一级
////            return chain.filter(exchange.mutate().request(request).build());
////        }
//        return chain.filter(exchange);
//    }
//
//
//    private Mono<Void> returnMono(GatewayFilterChain chain, ServerWebExchange exchange) {
//        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
//            Long startTime = exchange.getAttribute("startTime");
//            if (startTime != null) {
//                long executeTime = (System.currentTimeMillis() - startTime);
//                log.info("耗时：{}ms", executeTime);
//                log.info("状态码：{}", Objects.requireNonNull(exchange.getResponse().getStatusCode()).value());
//            }
//        }));
//    }
//
//    ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers, CachedBodyOutputMessage outputMessage) {
//        return new ServerHttpRequestDecorator(exchange.getRequest()) {
//            @Override
//            public HttpHeaders getHeaders() {
//                long contentLength = headers.getContentLength();
//                HttpHeaders httpHeaders = new HttpHeaders();
//                httpHeaders.putAll(super.getHeaders());
//                if (contentLength > 0L) {
//                    httpHeaders.setContentLength(contentLength);
//                } else {
//                    httpHeaders.set("Transfer-Encoding", "chunked");
//                }
//                return httpHeaders;
//            }
//
//            @Override
//            public Flux<DataBuffer> getBody() {
//                return outputMessage.getBody();
//            }
//        };
//    }
//
//
//    /**
//     * 处理params 参数
//     *
//     * @return 为url 字符串拼接内容，如： ?aldtype=16047&query=&keyfrom=baidu ，value值需 URLEncoder.encode
//     * @author ws
//     * @mail 1720696548@qq.com
//     * @date 2020/2/13 0013 23:52
//     */
//    private String handleParam(MultiValueMap<String, String> queryParams) {
//        // 处理get请求参数
//        if (queryParams.size() <= 0) {
//            return "";
//        }
//        // 参数处理
//        String newJsonQueryParams = JSONObject.toJSONString(queryParams).replaceAll("\\[", "").replaceAll("\\]", "");
//        Map<String, String> mapParams = JSONObject.parseObject(newJsonQueryParams, Map.class);
//        StringBuilder query = new StringBuilder();
//        for (String key : mapParams.keySet()) {
//            // 对原有的每个参数进行还原
//            query.append(key + "=" + java.net.URLEncoder.encode(mapParams.get(key)) + "&");
//        }
//        // sql 注入攻击处理
//        if (authProperties.isSqlReqAttack()) {
//            boolean passSqlInjection = SqlEncodeUtil.isPassSqlInjection(queryParams.toString());
//            if (!passSqlInjection) {
//                throw new ErrorException(ResultType.IS_NO_PARAM.getCode(), queryParams.toString() + " " + ResultType.IS_NO_PARAM.getMsg());
//            }
//        }
//        return query.toString().substring(0, query.length() - 1);
//    }
//
//
//    /**
//     *  处理 body参数
//     *
//     * @param bodyStr 请求boay数据
//     * @return boay
//     * @author ws
//     * @mail 1720696548@qq.com
//     * @date 2020/2/13 0013 23:52
//     */
//    private String handleBody(String bodyStr) {
//        if (bodyStr.isEmpty()) {
//            return "";
//        }
//        // sql 注入攻击处理
//        if (authProperties.isSqlReqAttack()) {
//            boolean passSqlInjection = SqlEncodeUtil.isPassSqlInjection(bodyStr);
//            if (!passSqlInjection) {
//                throw new ErrorException(ResultType.IS_NO_PARAM);
//            }
//        }
//        return bodyStr;
//    }
//}
